package at.jku.pervasive.recognition;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;

public class GesturePublisherThread extends Thread implements GesturePublisher
{

	private final Socket clientSocket;
	private final PrintWriter writer;

	private final LinkedList<GestureEvent> gestureEvents;

	private Semaphore semaphore;

	protected GesturePublisherThread(Socket clientSocket) throws IOException
	{
		this.clientSocket = clientSocket;
		OutputStream out = clientSocket.getOutputStream();
		this.writer = new PrintWriter(out);

		this.gestureEvents = new LinkedList<GestureEvent>();

		this.semaphore = new Semaphore(0);
	}

	@Override
	public void run()
	{
		while (this.clientSocket.isConnected())
		{
			try
			{
				this.semaphore.acquire();
				GestureEvent event = gestureEvents.pollFirst();
				this.writer.println(event.toString());
				this.writer.flush();
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}

	public void stopProducing()
	{
		try
		{
			this.clientSocket.close();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	@Override
	public void startProducing() throws IOException
	{
		start();
	}

	@Override
	public synchronized void gestureFinished(GestureType gestureType, long duration)
	{
		GestureEvent event = new GestureEvent(gestureType);
		event.setDurartion(duration);
		event.setEventType(GestureEventType.GESTURE_FINISHED);
		this.gestureEvents.addLast(event);
		this.semaphore.release();
	}

	@Override
	public void gestureStarted(GestureType gestureType, Date timestamp)
	{
		GestureEvent event = new GestureEvent(gestureType, timestamp);
		event.setEventType(GestureEventType.GESTURE_STARTED);
		this.gestureEvents.addLast(event);
		this.semaphore.release();
	}

}
